package com.atguigu.juc.threadlocal;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author yanglin
 * @create 2024-01-30 15:24 星期二
 * description:
 */
public class ThreadLocalDemo2 {
    
    /**
     * 【强制】必须回收自定义的ThreadLocal变量，尤其是在线程池场景下，线程经常会被复用，如果不清理自定义的ThreadLocal变量，
     *  可能会影响后续业务逻辑造成内存泄露问题，尽量在代理中使用try-finally 块进行回收
     */
    
    public static void main(String[] args) {
        MyData myData = new MyData();
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        try {
            for (int i = 0; i < 10; i++) {
                threadPool.submit(() -> {
                    Integer beforeInt;
                    Integer afterInt;
                    try {
                        beforeInt = myData.threadLocalField.get();
                        myData.add();
                        afterInt = myData.threadLocalField.get();
                    } finally {
                        myData.threadLocalField.remove();
                    }
                    System.out.println(Thread.currentThread().getName() + "\t beforeInt " + beforeInt + "\t afterInt " + afterInt);
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}

class MyData {
    ThreadLocal<Integer> threadLocalField = ThreadLocal.withInitial(() -> 0);
    
    public void add(){
        threadLocalField.set(threadLocalField.get() + 1);
    }
}
